/* rccl.h main header file****
**** Description of the Folders****
RCCL	main folder, with the simulator (python programs)
	in the same folder, the test programs for the emulator (RCCL...) and their makefile
  /Emul	the c programs for the emulator (the microprocessor) and their makefile
  /util	external programs
  /sd are the external programs for SD card
  /Models the Model files source=.mdx, code =.md  parameters=.mdp
  /Help The help files, in simple html
****Description of the simulator
	main.py , Calc.py(the logic) , Gui.py(the interface)  
****Description of the Emul c sources
rccl.h 	this header file 
calc.c 	 the  logic of the emulator for rccl language, written in C, without any I/O processing.
 	In other words, this is thue pure logic of this language, common to desktop and micro.
param.c	 the name of a parameter is hierarchical. This module is used to find a name in a list.
menu.c  all the menu processing
io_all.c the io functions processing , independant of the hardware
io_timer.c the support for the timers : PPM signal and clock
AVR_rccl is the main program for the emulator (other test programs begin with AVR_)
*** sources very depending on the hardware , micro, ports....
io.h     a header file with io , ports..
io.c     some ports definitions are in the function calls
**** util
*lcd routines from Fleury
	lcd.c lcd.h
*uart from the avr c library (examples), modified for the Atmega128


 */
 /*
# ============================================================================
# Copyright (C) 2008 2009 Robert Spilleboudt
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#============================================================================
*/
 /*______compilation mode__________________________
several modes are possible
the normal use is a stand alone transmitter,  PC connection with SD card, no UART -> do not define UART0 
	the arrays are maximum (check freeram to be sure)
the test mode occurs with #define TESTMODE
	-> #define UART0
	-> arrays leave free ram needed by the several printf test istructions
	-> other definition of the arrays


*/
/*    stack overflow is a real DANGER check the freeram (Menu Status)
*/
//#define LIBRAM      // if the parameters name are in RAM  
//#define LIBROM  // the parameters are in EEPROM
#define  LIBRAMROM   // mixed
#ifdef LIBRAM
	#define MAX_PARAM 1000 /* maximum space for parameter names*/
	#define MAX_PARAM_RAM 1000 /* RAM memory reserved*/
	#define MAX_PARAM_REF 1000  // for menu status
#endif
#ifdef LIBROM
	#define MAX_PARAM 3000/* maximum space for parameter names*/
	#define MAX_PARAM_REF 3000
#endif
#ifdef LIBRAMROM
	#define MAX_PARAM 3000 /* maximum space for parameter names*/
	#define MAX_PARAM_RAM 900 /* RAM memory reserved   -   */
	#define MAX_PARAM_REF 900
#endif
//#define TESTMODE
#ifdef TESTMODE
	#define UART0        //for the UART debug
	#define MAX_N 200 /* max num vars  max 254 !     */
	#define MAX_L 30 /* max logical vars*/
	#define MAX_OP  950 /* max operations codes (bytes)*/
#endif
#ifndef TESTMODE
	/*all the array sizes are defined here, */
	#define MAX_N 230 /* max num vars  max 254 !     */
	#define MAX_L 30/* max logical vars*/
	#define MAX_OP 1050 /* max operations codes (bytes)*/
	#define WDT    //if the watchdog is used  
#endif


/* eeprom memory  see lib.c*/
/* eprom memory allocation */
#define EE_POWER 1  //offset control byte
#define EE_PARAM_FIRST 50 //needed if the params are in eeprom
// eeprom parameters (MAX_PARAM) are allocated from top of eeprom
#define MAX_MODEL_NAME 30 /*max length model name*/
#define MAX_CURVE 30 /* max length CURVE/LINE = number of points *2*/
#define MAX_PARAM_NAME 30 /*max length model name*/
#define MAX_VAL 125 /* maximum value of a variable : normal from -100->+100 here from -125 to +125
   beware MAX_VAL*TOINT < 32767*/

/**** theses are also   defined in the python simulator */
#define MAX_LINE 100 /* max length of a .md line*/
#define TOINT  100 /* conversion factor from user variable (-100->+100) to integer internal variable*/
#define TOINT100 1 /* TOINT /100 */
#define TOINTx100 10000 /* TOINT *100 */
//#define SERIAL_COMMAND '$'
#define LCD_MESSAGE_SIZE 32 //maximum size of a message buffer 
//#define LCD_MESSAGE_DURATION    30000 /rc.clock_calc 0 // 2 sec
#define BEEPSTD 4 //duration of one short beep
//functions
//modules with a different coding on micro or PC
char* getline(char[] );// general interface routine / within the main AVR_rccl (or the main RCCL on the desktop)
void putack(void);
void param_export(void);
void param_import(void);

//void PC_print (char *s);


//common functions, for the micro or the testing on desktop
void reset(void);
int load(char line[]);
int inc (int *i , int max);// ++iop only if > max returns 0 if ok
void calc(void);
int curveS(int x,int xy[],int xylen);//polygone y=f(x)
int curve(int x, int xy[], int round); //returns f(x) curve profil xy round=0 straight round>0 rounded
int interpol(int x,int x1,int y1, int x2,int y2);
int valcheck(int var);//check a numeric value to the limites +110 -110
int trim(int stick,int mode,int trim);//trim correction 
void lcd_debug(const char *s, int delay);
//io functions
void io_init(void); //initialize all the io ports
void io_power(int power_on); //power on or off
uint8_t io_swread_one(uint8_t port,uint8_t bit);//read one digital io at port/bin 
void io_swread(void);//read all the switches and buttons
void io_set(void); //some io pins are depending on rc variables  (rccl.data structure)
//void io_dtrim(void);// process the digital trim buttons 
void io_butread100(void );//read thedigital trims
void io_butread5(void );//read menu buttons
uint8_t io_getButton(uint8_t index); //index of a state variable
int io_adc(int) ;//read one channel
void io_adc_all(void); //read all the channels and do the calibration
void _io_debounce(uint8_t index, uint8_t din);//* internal function for debounce 
void _io_tick( uint8_t index, uint8_t dirp,uint8_t dirm);
void io_ppm_init(void); 
void io_ppm_load(void) ; //loads the variables of N_tx to the internal table for the interrupt routine
void io_beep(void);
void io_beep_set(int duration);
void battery_monitor(void);
// uart0 functions, conditionnaly compiled
void	uart_init(void);
int	uart_putchar(char c, FILE *stream);
int	uart_getchar(FILE *stream);
//eeprom see lib.c
void lib_putchar(int i, char c); //put char at i in eeprom/ram 
char lib_getchar(int i);//get char at i in eeprom/ram
void ee_putchar(int i, char c); //pu char at i in eeprom
char ee_getchar(int i);//get char at i in eeprom
// functions for hierarchical parameters names and menu
void hgetVarText(char *text,int index) ;// returns the text for the parameter at N_tx[index]
char* htextlcd(char* text);//returns a text  right aligned max length f LCD
int searchName(char[]  ,int maxlength, char type);// lib=names as loaded  type =5 or 6
int hsearch(uint8_t);
int hgetFirst(void);
int hgetNext(int i);
void param_init(void); //init program: initialize the control data about parameters
void param_button(void);//test if a button is pushed to assign a parameter to the digital trim
uint8_t hgetMenuChoice(char[]); /*returns the user choice 
0=back,1=Up,2=Select,3=Down,4=Scroll Right,5=Scroll Left
enum choice {BACK=0,UP=1,SELECT=2,DOWN=3, LEFT=4,RIGHT=5};*/
uint8_t hgetMenuChoiceVariableLib(char[]); //idem without the rcloop
void getPhaseName( char[], int,int);
void getLCDmessage(char[],int);
//clock
void clock_init(void);
void lcd_time( int timer); //transform the timer in string at the cursor of the lcd
//lcd messages
void lcd_message(char *s);
//menus
void rcloop(int io_ppm);
void lcd_fly_info(void);
void menu_main(void); //first level menu
void menu_param_tune(void); //parameters updates
void menu_param_dt(void); //parameter assign to digital trim
void menu_param_dt_stop(void); //cancel the parameter assign to digital trim
void menu_status(void);//freeram and other  
void menu_off(void);// save parameters and power off (cut the regulator)
void menu_dumpOperations(void);//status of the opcodes (if UART0 , called by menu_status
void menu_calibrate(void);//calibrate the sticks
void menu_var_n(void);//value of each numerical  variable
void menu_var_l(void);//value of each logical  variable
void menu_adc(void);//value of each analog input (raw value, not calibrated)
void menu_pulse(void); //pulse generator
void menu_out(void);//all the @variables -> uart0 
//sd card

uint8_t  sd_init(void);
void sd_close(void);
//void sd_list_printf(void);
//void sd_write(char* s);
int sd_load(void);//menu choice of a model and  load the model from SD    
void sd_load_model(void); //load a model from the name rc.modelName
//automatic save restore at power on/off
void sd_save(void); //global parameters and filename current model
void sd_restore(void);
void sd_save_param(void);//parameters , shared with PC simulation
void sd_restore_param(void);
void sd_restore_calibrate(void);
//memory control
void stackmon(void);
int stackmargin(void);
int get_free_memory(void);



/* internal codification of opcodes see Calc.py 
OPCODE={ "PHASE": "P",  "INIT":"I", "ADD":"+", "+":"+","SUB":"-","-":"-","=":"=", "EXP":"E",\
    "MULT":"*","*":"*","OUTN":"O","TRIM":"T",  "TRIMA":"t","CURVE":"C","ADDS":"S","ADDAS":"A",\
    "SUBS":"s","SUBAS":"a","SERV":"r","AND":"0",  "OR":"1","NOT":"2","COMP":"3",\
    "NUM":"4","NUMT":"5",  "IF":"8","ENDIF":"9"}
*/
#define OP_EMPTY '255'
#define OP_EOF		 '?'  //OP_EOF is the end of operations or params
#define OP_IF     	'8'
#define OP_ENDIF  '9'
#define OP_PHASE  'P'
#define OP_SLOW  'W'
#define OP_INIT   	'I'
#define OP_ADD    '+'
#define OP_SUB    '-'
#define OP_MULT   '*'
#define OP_MULT_PC   '%'
#define OP_EQU    '='
#define OP_EQU_PARAM 'M'
#define OP_LINE   'L'
#define OP_CURVE  'C'
#define OP_EXPO   'E'
#define  OP_OUT   'O'
#define  OP_OUTN  'N'
#define  OP_SERV  'r'
#define  OP_ADDS  'S'
#define  OP_SUBS  's'
#define  OP_ADDAS 'A'
#define  OP_SUBAS 'a'
#define  OP_AND   '0'
#define  OP_OR    '1'
#define  OP_NOT   '2'
#define  OP_COMP  '3'
#define  OP_COMPH '6'
#define  OP_NUM   '4'
#define  OP_NUMT  '5'
#define OP_MEM '7'
#define  OP_CHRI 'w'
#define  OP_CHRPLUS 'x'
#define  OP_CHRMIN 'y'
#define OP_BEEP 'z'
#define OP_BREAK 'B'
#define OP_UPD 'U'
//This struct defines the main RAM data of the RCCL interpreter

struct rccl_data { /* the SRAM datas processed by the micro*/
	int16_t N_tx [MAX_N];/* numerical variables 16 bits*/
	uint8_t nvar_nH ; /* index of the first N_tx  variable to initialize  */
	uint8_t  L_tx[MAX_L]; /* logical variables*/
	uint8_t nvar_lH ;
	char  op [MAX_OP];  /* operations codes*/
	char  modelName[MAX_MODEL_NAME]; //current model as xxx_yyyyy : filename without extension, or empty string  
	uint8_t phase   ; /* the index in L_tx of the phase outvar variable  or 255 if there is no phase*/
	uint8_t phase_old   ; /* former phase - to detect a phase change*/
	int16_t v_before [ PPM_MAX_CH];
	int16_t   slow;/* 0 if no phase changed - >0 = progressive change during this number of cycles*/
	int16_t slow_done ; /* number of cycles after the phase change , already corrected*/
	int16_t slow_end ; /*number of cycles for the phase transition 
	correction after x cycles :
	slow_done=x
	correction = v_correction[channel] * (1-(slow_done/slow_end))
	*/
	uint8_t io_state[PARAM_N +2]; // state variable for a debounced button PARAM_N params buttons + MENU SELECT + AUTOTRIM
	uint8_t param_button[PARAM_N];// for inflight pameter update, foreach button , the index of the variable assigned to the buttion or 255
	uint8_t io_timer[DTRIM_N]; // timer for each digital trim, needed for acceleration after a long push
	uint8_t io_tick;// provides a acoustic tick when digital trims are changed by 1%
	uint8_t io_maxspeed;  // 1= maximum speed of a digital trim  if using a menu and the Lcd, 0= low speed , in flight
	uint8_t pvar[DTRIM_N];
	uint8_t vvar[DTRIM_N];
	uint16_t battery ; //voltage of the battery vv,vv
	uint16_t clock_timer_before ; //last value of timer3
	uint16_t clock_calc ; //number of computation loops / HS1 tick (1/100 minute)
	uint16_t clock_time_start; // increment each second
	uint16_t clock_timer_sticks ;// sticks not changing since this time
	uint8_t   clock_tick; // 1/100 minute tick
	int chrono_var[4]; //4 chronos for the 4 available positions (timer  variables in seconds /empty is > 60000 )
	uint16_t lcd_timer ;// a lcd message remains during this number of rc loops (not within menu navigation / only within the main prog )
	uint8_t   beep; //beeps if positive
	uint8_t   ibreak;//error message displayed
	long sticks ; //former position of the sticks  sum of the 4 sticks
	//calibration data for the analog inputs (ADC_CH channels )
	uint16_t adc_xa[ADC_CH]; // value read by the ADC for the lowest position (-100%)
	uint16_t adc_xc[ADC_CH]; // idem center position
	uint16_t adc_xb[ADC_CH]; //+100%
	//control data for hsearch 
	int proposed;//where we are in the explore of the parameters names, 0 if empty
	int nselpt;//number of separators in the selected filter
	//transmission PPM
	uint8_t PPM_ch; //number of channels
	uint16_t PPM_pulse;//PPM frame length in ticks !
	//memory use
	uint8_t nvar_n; //number of the allocated numeric variables
	uint8_t nvar_l; //number of the allocated logical variables
	uint16_t niop; // memory allcated to  operations
	uint16_t nlib ; //  memory allcated to  libs
	
	int stackmin; //lowest adress in the stack variables
	
} ;

struct rccl_lib{ //this structure is the list of the names - in RAM or EEPROM
	char name [MAX_PARAM_RAM]; /* the whole param and phase names 
	format of each element:
	- index +0:1 byte with the nature , now the line code '5' or '6'
		5 = phase name, index to logical variable
		6 = parameter name, index to numerical var
	-index+1: 1 byte with the index to the var
	-index+2 :1 byte =\0 , needed to read backward
	-index+3: a char string max length=MAX_NAME (terminated with \0)	*/
};



